package com.smartleanx.module.hrm.app.empRisk;

import cn.hutool.core.collection.CollUtil;
import com.smartleanx.framework.common.util.collection.CollectionUtils;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeContractDO;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeDO;
import com.smartleanx.module.hrm.dal.dataobject.risk.RiskTypeDO;
import com.smartleanx.module.hrm.enums.ErrorCodeConstants;
import com.smartleanx.module.hrm.eums.employee.EmployeeContractTypeEnum;
import com.smartleanx.module.hrm.eums.employee.EmploymentFormEnum;
import com.smartleanx.module.hrm.eums.risk.RiskLevelEnum;
import com.smartleanx.module.hrm.eums.risk.RiskTypeEnum;
import com.smartleanx.module.hrm.service.employee.EmployeeContractService;
import com.smartleanx.module.hrm.service.employee.EmployeeService;
import com.smartleanx.module.hrm.service.risk.RiskService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.smartleanx.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 试用期期限
 *
 * @author tengcj
 * @since 2024/6/11
 */
@Component
public class RiskTrialPeriodHandleService implements EmployeeRiskHandle {

    @Resource
    private EmployeeService employeeService;

    @Resource
    private EmployeeContractService employeeContractService;

    @Resource
    private RiskService riskService;

    public static final long RISK_ID = RiskTypeEnum.PROBATION_PERIOD.getCode();

    @Override
    public Long type() {
        return RISK_ID;
    }

    @Override
    public void handleEmployeeRisk(Set<Long> employeeIds) {
        List<EmployeeDO> employeeList = employeeService.getEmployeeList(employeeIds);
        if (CollUtil.isEmpty(employeeList)) {
            riskService.deleteRisk(employeeIds, RISK_ID);
            return;
        }
        RiskTypeDO riskType = riskService.getRiskType(RISK_ID);
        if (riskType == null) {
            throw exception(ErrorCodeConstants.RISK_TYPE_NOT_EXISTS);
        }

        Map<Long, List<EmployeeContractDO>> contractMap = CollectionUtils.convertMultiMap(
                employeeContractService.getInProgressContractList(employeeIds), EmployeeContractDO::getEmployeeId
        );

        for (EmployeeDO employeeDO : employeeList) {
            if (Objects.equals(EmploymentFormEnum.INFORMAL.getCode(), employeeDO.getEmploymentForm())) {
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
                continue;
            }
            List<EmployeeContractDO> contractList = contractMap.get(employeeDO.getId());
            if (CollUtil.isEmpty(contractList)) {
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
                continue;
            }
            EmployeeContractDO contract = CollectionUtils.findFirst(contractList, Objects::nonNull);
            if (contract == null) {
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
                continue;
            }

            Integer probationPeriod = employeeDO.getProbationPeriod();

            if (!EmployeeContractTypeEnum.FIXED_TERM.gettype().equals(contract.getContractType())) {
                if (probationPeriod > 6) {
                    riskService.addRiskToEmployee(employeeDO.getId(), riskType.getId(), RiskLevelEnum.MAJOR.getLevel());
                    continue;
                }
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
                continue;
            }

            // long between = ChronoUnit.YEARS.between(startTime, endTime);
            Integer term = contract.getTerm();

            if (term >= 3 && probationPeriod > 6) {
                riskService.addRiskToEmployee(employeeDO.getId(), RISK_ID, RiskLevelEnum.MAJOR.getLevel());
                continue;
            }

            if (term >= 1 && term < 3 && probationPeriod > 2) {
                riskService.addRiskToEmployee(employeeDO.getId(), RISK_ID, RiskLevelEnum.MAJOR.getLevel());
                continue;
            }

            riskService.deleteRisk(employeeDO.getId(), RISK_ID);
        }

    }

}
